/**
 * 
 */
package ads.engenharia.bl;

import java.sql.SQLException;
import java.util.ArrayList;

import ads.engenharia.dal.DisciplineDAO;
import ads.engenharia.dal.DisciplineProfessorDAO;
import ads.engenharia.dal.DisciplineScheduleDAO;
import ads.engenharia.entity.Course;
import ads.engenharia.entity.Discipline;
import ads.engenharia.entity.Professor;
import ads.engenharia.entity.Schedule;
import ads.engenharia.manager.DALManager;

//TODO: Associate should display only available professors with competence for discipline!
//TODO: Associate should remove previously associated professor with discipline like course!

/**
 * @author Lanedraex
 *
 */
public class DisciplineBO {

	private DisciplineDAO _disciplineDAO;
	private DisciplineScheduleDAO _disciplineScheduleDAO;
	private DisciplineProfessorDAO _disciplineProfessorDAO;
	private ProfessorBO _professorBO;

	public DisciplineBO() {

		// _disciplineDAO = new DisciplineDAO();
		// _disciplineScheduleDAO = new DisciplineScheduleDAO();
		// _disciplineProfessorDAO = new DisciplineProfessorDAO();
		// _professorBO = new ProfessorBO();
	}

	/**
	 * 
	 * @param discipline
	 * @throws SQLException
	 */
	public void save(Discipline discipline) throws SQLException {

		// discipline.id(_disciplineDAO.save(discipline).id());
		// _disciplineScheduleDAO.save(discipline);

		discipline.id(DALManager.Instance().disciplineDAO().save(discipline)
				.id());
		DALManager.Instance().disciplineScheduleDAO().save(discipline);

	}

	/**
	 * 
	 * @param discipline
	 * @throws SQLException
	 */
	public void associateDisciplineProfessor(Discipline discipline)
			throws SQLException {

		// _disciplineProfessorDAO.save(discipline);

		Professor professor = discipline.professor();

		// DEBUG
		System.out.println("Professor details: " + professor.id() + " "
				+ professor.name() + " " + professor.workload());

		if (professor != null) {

			// DEBUG
			System.out.println("professor workload before = "
					+ professor.workload());

			professor.workload(professor.workload() - 2);

			// DEBUG
			System.out.println("professor workload after = "
					+ professor.workload());

			DALManager.Instance().professorBO().update(professor);
		}

		DALManager.Instance().disciplineProfessorDAO().delete(discipline);
		DALManager.Instance().disciplineProfessorDAO().save(discipline);
	}

	/**
	 * 
	 * @param discipline
	 * @throws SQLException
	 */
	public void delete(Discipline discipline) throws SQLException {

		// _disciplineDAO.delete(discipline);

		DALManager.Instance().disciplineDAO().delete(discipline);

	}

	/**
	 * 
	 * @param discipline
	 * @throws SQLException
	 */
	public void update(Discipline discipline) throws SQLException {

		// _disciplineDAO.update(discipline);
		// _disciplineScheduleDAO.update(discipline);
		// if (discipline.professor() != null)
		// _disciplineProfessorDAO.update(discipline);

		DALManager.Instance().disciplineDAO().update(discipline);
		DALManager.Instance().disciplineScheduleDAO().update(discipline);
		if (discipline.professor() != null) {
			DALManager.Instance().disciplineProfessorDAO().save(discipline);
		}
	}

	/**
	 * 
	 * @param discipline
	 * @return
	 * @throws SQLException
	 */
	public Discipline search(Discipline discipline) throws SQLException {

		// // Searches for discipline details and schedule
		// discipline = _disciplineDAO.search(discipline);
		// discipline.schedule(_disciplineScheduleDAO
		// .searchDisciplineSchedule(discipline));
		//
		// // Searches for professor
		// Professor professor = _disciplineProfessorDAO
		// .searchDisciplineProfessor(discipline);
		// professor = _professorBO.search(professor);
		// discipline.professor(professor);

		// Searches for discipline details and schedule
		discipline = DALManager.Instance().disciplineDAO().search(discipline);
		discipline.schedule(DALManager.Instance().disciplineScheduleDAO()
				.searchDisciplineSchedule(discipline));

		// Searches for professor
		Professor professor = DALManager.Instance().disciplineProfessorDAO()
				.searchDisciplineProfessor(discipline);
		if (professor != null) {
			professor = DALManager.Instance().professorBO().search(professor);
			discipline.professor(professor);
		}
		return discipline;
	}

	/**
	 * 
	 * @return
	 * @throws SQLException
	 */
	public ArrayList<Discipline> searchAll() throws SQLException {

		// ArrayList<Discipline> disciplines;
		// disciplines = _disciplineDAO.searchAll();
		//
		// for (Discipline d : disciplines) {
		// d.schedule(_disciplineScheduleDAO.searchDisciplineSchedule(d));
		//
		// // Searches for professor
		// Professor professor = _disciplineProfessorDAO
		// .searchDisciplineProfessor(d);
		// professor = _professorBO.search(professor);
		// d.professor(professor);
		// }

		ArrayList<Discipline> disciplines;
		disciplines = DALManager.Instance().disciplineDAO().searchAll();

		for (Discipline d : disciplines) {
			d.schedule(DALManager.Instance().disciplineScheduleDAO()
					.searchDisciplineSchedule(d));

			// Searches for professor
			Professor professor = new Professor();
			professor = DALManager.Instance().disciplineProfessorDAO()
					.searchDisciplineProfessor(d);
			professor = DALManager.Instance().professorBO().search(professor);
			d.professor(professor);
		}

		return disciplines;

	}

	/**
	 * 
	 * @param id
	 * @return
	 * @throws SQLException
	 */
	public Discipline searchById(int id) throws SQLException {

		// Discipline discipline;
		// discipline = _disciplineDAO.searchById(id);
		// discipline.schedule(_disciplineScheduleDAO
		// .searchDisciplineSchedule(discipline));
		//
		// // Searches for professor
		// Professor professor = _disciplineProfessorDAO
		// .searchDisciplineProfessor(discipline);
		// professor = _professorBO.search(professor);
		// discipline.professor(professor);

		Discipline discipline;
		discipline = DALManager.Instance().disciplineDAO().searchById(id);
		discipline.schedule(DALManager.Instance().disciplineScheduleDAO()
				.searchDisciplineSchedule(discipline));

		// Searches for professor
		Professor professor = DALManager.Instance().disciplineProfessorDAO()
				.searchDisciplineProfessor(discipline);
		professor = DALManager.Instance().professorBO().search(professor);
		discipline.professor(professor);

		return discipline;

	}

	/**
	 * 
	 * @return
	 * @throws SQLException
	 */
	public Discipline searchByMaxId() throws SQLException {

		// Discipline discipline;
		// discipline = _disciplineDAO.searchByMaxId();
		// discipline.schedule(_disciplineScheduleDAO
		// .searchDisciplineSchedule(discipline));
		//
		// // Searches for professor
		// Professor professor = _disciplineProfessorDAO
		// .searchDisciplineProfessor(discipline);
		// professor = _professorBO.search(professor);
		// discipline.professor(professor);

		Discipline discipline;
		discipline = DALManager.Instance().disciplineDAO().searchByMaxId();
		discipline.schedule(DALManager.Instance().disciplineScheduleDAO()
				.searchDisciplineSchedule(discipline));

		// Searches for professor
		Professor professor = DALManager.Instance().disciplineProfessorDAO()
				.searchDisciplineProfessor(discipline);
		professor = DALManager.Instance().professorBO().search(professor);
		discipline.professor(professor);

		return discipline;

	}

	/**
	 * 
	 * @param name
	 * @return
	 * @throws SQLException
	 */
	public ArrayList<Discipline> searchByName(String name) throws SQLException {

		// ArrayList<Discipline> disciplines;
		// disciplines = _disciplineDAO.searchByName(name);
		//
		// for (Discipline d : disciplines) {
		// d.schedule(_disciplineScheduleDAO.searchDisciplineSchedule(d));
		//
		// // Searches for professor
		// Professor professor = _disciplineProfessorDAO
		// .searchDisciplineProfessor(d);
		// professor = _professorBO.search(professor);
		// d.professor(professor);
		//
		// }

		ArrayList<Discipline> disciplines;
		disciplines = DALManager.Instance().disciplineDAO().searchByName(name);

		for (Discipline d : disciplines) {
			d.schedule(DALManager.Instance().disciplineScheduleDAO()
					.searchDisciplineSchedule(d));

			// Searches for professor
			Professor professor = new Professor();
			professor = DALManager.Instance().disciplineProfessorDAO()
					.searchDisciplineProfessor(d);

			if (professor != null) {
				professor = DALManager.Instance().professorBO()
						.search(professor);
				d.professor(professor);
			}
		}

		return disciplines;

	}

	/**
	 * 
	 * @param duration
	 * @return
	 * @throws SQLException
	 */
	public ArrayList<Discipline> searchByDuration(int duration)
			throws SQLException {

		// ArrayList<Discipline> disciplines;
		// disciplines = _disciplineDAO.searchByDuration(duration);
		//
		// for (Discipline d : disciplines) {
		// d.schedule(_disciplineScheduleDAO.searchDisciplineSchedule(d));
		//
		// // Searches for professor
		// Professor professor = _disciplineProfessorDAO
		// .searchDisciplineProfessor(d);
		// professor = _professorBO.search(professor);
		// d.professor(professor);
		//
		// }

		ArrayList<Discipline> disciplines;
		disciplines = DALManager.Instance().disciplineDAO()
				.searchByDuration(duration);

		for (Discipline d : disciplines) {
			d.schedule(DALManager.Instance().disciplineScheduleDAO()
					.searchDisciplineSchedule(d));

			// Searches for professor
			Professor professor = DALManager.Instance()
					.disciplineProfessorDAO().searchDisciplineProfessor(d);
			professor = DALManager.Instance().professorBO().search(professor);
			d.professor(professor);

		}

		return disciplines;

	}

	/**
	 * 
	 * @param day
	 * @return
	 * @throws SQLException
	 */
	public ArrayList<Discipline> searchByDay(Schedule.Day day)
			throws SQLException {

		ArrayList<Discipline> disciplines;
		disciplines = _disciplineDAO.searchByDay(day);

		for (Discipline d : disciplines) {
			d.schedule(_disciplineScheduleDAO.searchDisciplineSchedule(d));

			// Searches for professor
			Professor professor = _disciplineProfessorDAO
					.searchDisciplineProfessor(d);
			professor = _professorBO.search(professor);
			d.professor(professor);

		}

		return disciplines;
	}

	/**
	 * 
	 * @param time
	 * @return
	 * @throws SQLException
	 */
	public ArrayList<Discipline> searchByTime(Schedule.Time time)
			throws SQLException {

		ArrayList<Discipline> disciplines;
		disciplines = _disciplineDAO.searchByTime(time);

		for (Discipline d : disciplines) {
			d.schedule(_disciplineScheduleDAO.searchDisciplineSchedule(d));

			// Searches for professor
			Professor professor = _disciplineProfessorDAO
					.searchDisciplineProfessor(d);
			professor = _professorBO.search(professor);
			d.professor(professor);

		}

		return disciplines;
	}

	/**
	 * 
	 * @param hour
	 * @return
	 * @throws SQLException
	 */
	public ArrayList<Discipline> searchByHour(Schedule.Hour hour)
			throws SQLException {

		ArrayList<Discipline> disciplines;
		disciplines = _disciplineDAO.searchByHour(hour);

		for (Discipline d : disciplines) {
			d.schedule(_disciplineScheduleDAO.searchDisciplineSchedule(d));

			// Searches for professor
			Professor professor = _disciplineProfessorDAO
					.searchDisciplineProfessor(d);
			professor = _professorBO.search(professor);
			d.professor(professor);

		}

		return disciplines;
	}

	public ArrayList<Discipline> searchByCourse(String courseName)
			throws SQLException {

		CourseBO courseBO = new CourseBO();
		ArrayList<Course> courses = courseBO.searchByName(courseName);
		ArrayList<Discipline> disciplines = new ArrayList<Discipline>();

		for (Course c : courses)
			disciplines.addAll(c.program());

		return disciplines;

	}
}
